package dao

import (
	"context"
	"encoding/json"
	"epai/internal/model"
	"errors"
	"gorm.io/gorm"
	"pkg/address"
	"time"
)

type Goods struct {
	GoodsId string `json:"goods_id"`
	Name    string `json:"name"`
	Cover   string `json:"cover"`

	Tags     string   `json:"tags,omitempty"`
	TagArr   []string `gorm:"-" json:"tag_arr"`
	Imgs     string   `json:"imgs,omitempty"`
	ImgArr   []string `gorm:"-" json:"img_arr"`
	Videos   string   `json:"videos,omitempty"`
	VideoArr []string `gorm:"-" json:"video_arr"`

	GoodsCategoryId   string `json:"goods_category_id"`
	GoodsCategoryName string `json:"goods_category_name"`
}

type GetShopResult struct {
	ShopId    string  `json:"shop_id"`
	Name      string  `json:"name"`
	Address   string  `json:"address"`
	Longitude float64 `json:"longitude"`
	Latitude  float64 `json:"latitude"`

	MobilePhone       string `json:"mobile_phone"`
	EstablishmentDate uint64 `json:"establishment_date"`

	ShopExtPaoziId     string `json:"shop_ext_paozi_id"`
	Sex                string `json:"sex"`
	ChestCircumference string `json:"chest_circumference"`
	WaistCircumference int    `json:"waist_circumference"`
	HipCircumference   int    `json:"hip_circumference"`
	ShoeSize           int    `json:"shoe_size"`
	XiaoHongShuFans    int    `json:"xiao_hong_shu_fans"`
	DouYinFans         int    `json:"dou_yin_fans"`
	KuaiShouFans       int    `json:"kuai_shou_fans"`
	BZhanFans          int    `json:"bzhan_fans"`
	WeiBoFans          int    `json:"wei_bo_fans"`

	Height float64 `json:"height"`
	Weight float64 `json:"weight"`

	GoodsSize int     `gorm:"-" json:"goods_size"`
	Goods     []Goods `gorm:"-" json:"goods"`
}

type GetShopListResult struct {
	ShopId    string  `json:"shop_id"`
	Name      string  `json:"name"`
	Address   string  `json:"address"`
	Longitude float64 `json:"longitude"`
	Latitude  float64 `json:"latitude"`

	MobilePhone       string `json:"mobile_phone"`
	EstablishmentDate uint64 `json:"establishment_date"`

	ShopExtPaoziId     string `json:"shop_ext_paozi_id"`
	Sex                string `json:"sex"`
	ChestCircumference string `json:"chest_circumference"`
	WaistCircumference int    `json:"waist_circumference"`
	HipCircumference   int    `json:"hip_circumference"`
	ShoeSize           int    `json:"shoe_size"`
	XiaoHongShuFans    int    `json:"xiao_hong_shu_fans"`
	DouYinFans         int    `json:"dou_yin_fans"`
	KuaiShouFans       int    `json:"kuai_shou_fans"`
	BZhanFans          int    `json:"bzhan_fans"`
	WeiBoFans          int    `json:"wei_bo_fans"`

	Height float64 `json:"height"`
	Weight float64 `json:"weight"`
}

// AddShops 将表格数据解析到商店数据表
func AddShops(ctx context.Context, db *gorm.DB, data map[string][]string, addressToLR map[string]address.LR) error {
	count := len(data["shopID"])
	// 对每个商店单独处理
	for i := 0; i < count; i++ {
		establishmentDate, err := time.Parse("2006/1/2 15:04", data["入驻时间"][i]) // 对入驻时间转成时间戳，方便时间上的操作
		if err != nil {
			return err
		}
		record := model.Shop{
			Name:              data["姓名"][i],
			ShopType:          "paozi",
			ShopId:            data["shopID"][i],
			MobilePhone:       data["手机号"][i],
			Address:           data["所在区域"][i],
			Longitude:         addressToLR[data["所在区域"][i]].L,
			Latitude:          addressToLR[data["所在区域"][i]].R,
			EstablishmentDate: uint64(establishmentDate.Unix()),
		}
		// 更新记录，如果记录不存在则创建新记录
		err = db.Where(model.Shop{ShopId: record.ShopId}).Assign(record).FirstOrCreate(&record).Error
		if err != nil {
			return err
		}

		// 对第i个商家增加袍子（商店的扩展信息），如果对应袍子存在则更新记录，具体逻辑在AddPaozi()中实现
		_, err = AddPaozi(ctx, db, data, i)
		if err != nil {
			return err
		}
	}
	return nil
}

// DelShop 删除单个商店
func DelShop(ctx context.Context, db *gorm.DB, ShopId string) error {
	Shop := &model.Shop{}
	err := db.WithContext(ctx).Where("Shop_id = ?", ShopId).Delete(Shop).Error
	return err
}

// DelShopSlice 批量删除商店（同时为了完整性，把shop_ext_paozi对应的数据也一起删了）
func DelShopSlice(ctx context.Context, db *gorm.DB, ShopId []string) error {
	// 直接开删
	_ = db.WithContext(ctx).Where("shop_id IN ?", ShopId).Delete(&model.Shop{}).Error // 错误忽略，后面还要处理
	err := db.WithContext(ctx).Where("shop_id IN ?", ShopId).Delete(&model.ShopExtPaozi{}).Error
	if err != nil {
		return err
	}
	return err
}

// GetShop 获取单个商店信息
func GetShop(ctx context.Context, db *gorm.DB, ShopId string) (GetShopResult, error) {
	var result GetShopResult

	err := db.WithContext(ctx).
		Model(&model.Shop{}).Select("epai_shop.*,epai_shop_ext_paozi.*").
		Joins("left join epai_shop_ext_paozi on epai_shop.shop_id = epai_shop_ext_paozi.shop_id").
		First(&result).Error
	if err != nil {
		return result, err
	}

	err = db.WithContext(ctx).
		Model(&model.Goods{}).Select("epai_goods.*,epai_shop_ext_paozi.*,"+
		"epai_goods_category.name as goods_category_name").
		Joins("left join epai_goods_category on epai_goods.goods_category_id = epai_goods_category.goods_category_id").
		Joins("left join epai_shop_ext_paozi on epai_goods.shop_id = epai_shop_ext_paozi.shop_id").
		Where("epai_goods.shop_id = ?", ShopId).
		Limit(100000).Offset((1 - 1) * 100000).
		Find(&result.Goods).Error
	if err != nil {
		return result, err
	}
	for i := 0; i < len(result.Goods); i++ {
		_ = json.Unmarshal([]byte(result.Goods[i].Tags), &result.Goods[i].TagArr)
		result.Goods[i].Tags = ""
		_ = json.Unmarshal([]byte(result.Goods[i].Imgs), &result.Goods[i].ImgArr)
		result.Goods[i].Imgs = ""
		_ = json.Unmarshal([]byte(result.Goods[i].Videos), &result.Goods[i].VideoArr)
		result.Goods[i].Videos = ""
	}
	result.GoodsSize = len(result.Goods)
	return result, nil
}

// GetShopList 获取商店列表
func GetShopList(ctx context.Context, db *gorm.DB, page int, size int) ([]GetShopListResult, error) {
	var result []GetShopListResult

	err := db.WithContext(ctx).
		Model(&model.Shop{}).Select("epai_shop.*,epai_shop_ext_paozi.*").
		Joins("left join epai_shop_ext_paozi on epai_shop.shop_id = epai_shop_ext_paozi.shop_id").
		Limit(size).Offset((page - 1) * size).
		Find(&result).Error
	if err != nil {
		return result, err
	}
	return result, nil
}

// GetShopSum 获取商店数量
func GetShopSum(ctx context.Context, db *gorm.DB) (int64, error) {
	var count int64
	err := db.WithContext(ctx).Model(&model.Shop{}).Count(&count).Error
	return count, err
}

// GetAllShopId 获取所有商店id
func GetAllShopId(ctx context.Context, db *gorm.DB) ([]string, error) {
	var result []string
	err := db.WithContext(ctx).Model(&model.Shop{}).Pluck("shop_id", &result).Error
	if err != nil {
		return nil, err
	}
	return result, err
}

func GetSingle(ctx context.Context, db *gorm.DB, shopID string) (*model.Shop, error) {
	result := &model.Shop{}
	err := db.WithContext(ctx).
		Model(&model.Shop{}).Select("*").
		Where("shop_id = ?", shopID).First(result).Error
	if err != nil {
		return nil, err
	}
	return result, nil
}

// GetAllShopAddress 获取所有商店所在区域
func GetAllShopAddress(ctx context.Context, db *gorm.DB) ([]string, error) {
	var result []string
	err := db.WithContext(ctx).Model(&model.Shop{}).Pluck("address", &result).Error
	if err != nil {
		return nil, err
	}
	return result, err
}

// GetPushShopInfo 获取商品是否推流的信息
func GetPushShopInfo(ctx context.Context, db *gorm.DB, shopID string) (bool, error) {
	var goods model.Goods
	err := db.WithContext(ctx).Model(&model.Goods{}).Select("id").Where("shop_id = ? and is_push_flow = 1", shopID).First(&goods).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return false, nil
		}
		return false, err
	}
	if goods.ID != 0 {
		return true, nil
	}
	return false, nil
}
